package com.cdty.chess.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/v1/file")
public class File1Controller
{
    //文件上传目录所在路径
    private static final String UPLOAD_PATH = System.getProperty("user.dir") + "/fileupload/";
    private static final ObjectMapper om = new ObjectMapper();
    //用于记录同名文件个数
    private static Map<String,Integer> mp = new HashMap<>();

    /**
     * 文件上传
     * @param files
     * @throws Exception
     */
    @PostMapping("/fileUpload")
    public String fileUpload(@RequestParam("files") MultipartFile[] files) throws Exception
    {
        if(files != null)
        {
            //多文件上传，遍历每个文件
            for(MultipartFile file : files)
            {
                //获取上传文件的原始文件名
                String fileName = file.getOriginalFilename();
                //fileName+时间戳保证唯一性
                String timestamp = String.valueOf(System.currentTimeMillis());
                fileName = timestamp + fileName;
                //将文件上传目录和文件名拼接成完整的文件路径
                String filePath = UPLOAD_PATH+fileName;

                //transferTo()方法将上传的文件保存到指定的文件路径
                try {
                    file.transferTo(new File(filePath));
                    return fileName;
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 获取所有已上传文件的文件名
     * @return
     * @throws Exception
     */
    @GetMapping("/fileNameList")
    public String fileNameList() throws Exception
    {
        //根据路径创建对应的目录
        File directory = new File(UPLOAD_PATH);

        //存储该目录下的所有文件名
        List<String> fileNameList = new ArrayList<>();

        //判断该目录是否存在，并且是有效目录
        if(directory.exists() && directory.isDirectory())
        {
            //获取该目录下的所有文件和子目录
            File[] files = directory.listFiles();

            //该目录不是空目录
            if(files != null)
            {
                for(File file : files)
                {
                    //判断每个File对象是否是文件，是则获取文件名
                    if(file.isFile()) fileNameList.add(file.getName());
                }
            }
        }

        //将文件名集合转换为JSON格式的字符串返回给前端
        return om.writeValueAsString(fileNameList);
    }

    /**
     * 注解@PathVariable和@RequestParam注解的区别：
     * 若请求URL为/file/fileDownload/值，则使用@GetMapping("/fileDownload/{fileName}")、@PathVariable("fileName")
     * 若请求URL为/file/fileDownload?fileName=值，则使用@GetMapping("/fileDownload")、@RequestParam("fileName")
     * @param fileName
     * @return
     * @throws Exception
     */
    @GetMapping("/fileDownload/{fileName}")
    public ResponseEntity<byte[]> fileDownload(@PathVariable("fileName") String fileName) throws Exception
    {
        //根据指定文件路径创建文件对象
        //File.separator表示当前操作系统使用的文件分隔符
        File file = new File(UPLOAD_PATH + File.separator + fileName);

        //设置消息头信息
        HttpHeaders headers = new HttpHeaders();
        //对文件名进行UTF-8编码，防止中文乱码
        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
        //通知浏览器以下载的方式打开文件
        headers.setContentDispositionFormData("attachment", fileName);
        //通知浏览器以流的形式下载
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        //使用SpringMVC框架的ResponseEntity对象封装返回下载数据
        return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
    }
}
